package com.javasm.crm.service.repository.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.javasm.crm.domin.criteria.repositrory.OutRepoCriteria;
import com.javasm.crm.domin.entity.aftersale.Outorder;
import com.javasm.crm.domin.entity.aftersale.RefacOutApply;
import com.javasm.crm.domin.entity.aftersale.RefacOutGoods;
import com.javasm.crm.domin.entity.base.BaseEntity;
import com.javasm.crm.domin.entity.repository.Defective;
import com.javasm.crm.domin.entity.repository.Outrepo;
import com.javasm.crm.domin.entity.repository.Outrepogoods;
import com.javasm.crm.domin.vo.repository.OutrepoVO;
import com.javasm.crm.domin.vo.repository.OutrepogoodsVO;
import com.javasm.crm.mapper.repository.OutrepoMapper;
import com.javasm.crm.mapper.repository.OutrepogoodsMapper;
import com.javasm.crm.service.aftersale.IOutorderService;
import com.javasm.crm.service.aftersale.IRefacOutApplyService;
import com.javasm.crm.service.aftersale.IRefacOutGoodsService;
import com.javasm.crm.service.repository.IDefectiveService;
import com.javasm.crm.service.repository.IOutrepoService;
import com.javasm.crm.service.repository.IOutrepogoodsService;
import com.javasm.crm.utils.transfer.OutrepoGoodsTransfer;
import org.apache.ibatis.annotations.Result;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lirui
 * @since 2021-07-16
 */
@Service
@Transactional
public class OutrepoServiceImpl extends ServiceImpl<OutrepoMapper, Outrepo> implements IOutrepoService {

    @Resource
    private IOutorderService outorderService;

    @Resource
    private IOutrepogoodsService outrepogoodsService;

    @Resource
    private OutrepoGoodsTransfer outrepoGoodsTransfer;

    @Resource
    private IRefacOutGoodsService outGoodsService;

    @Resource
    private IDefectiveService defectiveService;

    @Resource
    private  IRefacOutApplyService outApplyService;


    @Override
    public boolean generateOutRepo(Integer id, String userName) {

        Outorder outorder = outorderService.getById(id);

        //生成出库单
        Outrepo outrepo = new Outrepo();
        outrepo.setCreateBy(userName);
        outrepo.setOutorderId(id);
        outrepo.setOutorderCode(outorder.getOutorderCode());
        outrepo.setApplyId(outorder.getApplyId());
        outrepo.setApplyCode(outorder.getApplyCode());
        outrepo.setType(outorder.getType());
        outrepo.setStatus(1);

        boolean save = save(outrepo);

        if (!save) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }

        //更新出库单单号
        String outrepoCode = "FC" + UUID.randomUUID().toString().substring(0, 5) + outrepo.getId();

        UpdateWrapper<Outrepo> outrepoUpdateWrapper = new UpdateWrapper<>();
        LambdaUpdateWrapper<Outrepo> outrepoLambdaUpdateWrapper = outrepoUpdateWrapper.lambda();
        outrepoLambdaUpdateWrapper.eq(BaseEntity::getId, outrepo.getId()).set(Outrepo::getOutrepoCode, outrepoCode);

        boolean updateOutrepo = update(outrepoUpdateWrapper);

        if (!updateOutrepo) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }

        //更新出库订单的生成状态
        UpdateWrapper<Outorder> outorderUpdateWrapper = new UpdateWrapper<>();
        LambdaUpdateWrapper<Outorder> outorderLambdaUpdateWrapper = outorderUpdateWrapper.lambda();

        outorderLambdaUpdateWrapper.eq(BaseEntity::getId, id).set(Outorder::getGened, 1);

        boolean updateOutOrder = outorderService.update(outorderLambdaUpdateWrapper);

        if (!updateOutOrder) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }

        //生成物品单
        Integer applyId = outorder.getApplyId();
        QueryWrapper<RefacOutGoods> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<RefacOutGoods> lambda = queryWrapper.lambda();

        lambda.eq(RefacOutGoods::getOdoId, applyId);
        List<RefacOutGoods> outGoods = outGoodsService.list(queryWrapper);

        List<Outrepogoods> outrepogoods = outrepoGoodsTransfer.toEntity(outGoods);

        for (Outrepogoods outrepogood : outrepogoods) {
            outrepogood.setOutrepoId(Integer.valueOf(outrepo.getId().toString()));
            outrepogood.setOutrepoCode(outrepo.getOutorderCode());
        }

        boolean saveBatch = outrepogoodsService.saveBatch(outrepogoods);


        return true;
    }

    @Override
    public Page<Outrepo> getOutRepo(OutRepoCriteria outRepoCriteria) {

        Integer currentPage = outRepoCriteria.getCurrentPage();
        Integer pageSize = outRepoCriteria.getPageSize();

        QueryWrapper<Outrepo> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<Outrepo> lambda = queryWrapper.lambda();

        String outorderCode = outRepoCriteria.getOutorderCode();
        if (outorderCode != null && !"".equals(outorderCode)) {
            lambda.like(Outrepo::getOutorderCode, outorderCode);
        }

        String outrepoCode = outRepoCriteria.getOutrepoCode();
        if (outrepoCode != null && !"".equals(outrepoCode)) {
            lambda.like(Outrepo::getOutrepoCode, outrepoCode);
        }

        Integer type = outRepoCriteria.getType();
        if (type != null) {
            lambda.eq(Outrepo::getType, type);
        }

        Integer status = outRepoCriteria.getStatus();
        if (status != null) {
            lambda.eq(Outrepo::getStatus, status);
        }

        LocalDateTime startTime = outRepoCriteria.getStartTime();
        LocalDateTime endTime = outRepoCriteria.getEndTime();
        if (startTime != null && endTime != null) {
            lambda.between(BaseEntity::getCreateTime, startTime, endTime);
        }

        lambda.orderByDesc(BaseEntity::getCreateTime);

        Page<Outrepo> page = new Page<>(currentPage, pageSize);
        page(page, queryWrapper);

        return page;
    }

    @Override
    public List<OutrepogoodsVO> getGoods(Integer applyId) {


        QueryWrapper<OutrepogoodsVO> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("afgs.odo_id", applyId)
                .eq("rpgs.deleted", 0)
                .eq("afgs.deleted", 0);

        List<OutrepogoodsVO> outrepogoodsVO = outrepogoodsService.getOutrepogoodsVO(queryWrapper);

        return outrepogoodsVO;
    }

    @Override
    public boolean enter(OutrepoVO outrepoVO) {

        //修改商品
        List<Outrepogoods> goodList = outrepoVO.getGoodList();
        Outrepo outrepo = outrepoVO.getOutrepo();

        for (Outrepogoods outrepogoods : goodList) {
            UpdateWrapper<Outrepogoods> outrepogoodsUpdateWrapper = new UpdateWrapper<>();
            LambdaUpdateWrapper<Outrepogoods> outrepogoodsLambdaUpdateWrapper = outrepogoodsUpdateWrapper.lambda();
            outrepogoodsLambdaUpdateWrapper.eq(Outrepogoods::getGoodImei, outrepogoods.getGoodImei())
                    .set(Outrepogoods::getGoodOutimei, outrepogoods.getGoodOutimei());
            boolean update = outrepogoodsService.update(outrepogoodsUpdateWrapper);
        }

        UpdateWrapper<Outrepo> updateWrapper = new UpdateWrapper<>();
        LambdaUpdateWrapper<Outrepo> lambda = updateWrapper.lambda();

        lambda.eq(BaseEntity::getId, outrepo.getId())
                .set(Outrepo::getComments, outrepo.getComments())
                .set(Outrepo::getStatus, 2)
                .set(Outrepo::getApproveStatus, 1)
                .set(Outrepo::getApproveComments, "")
                .set(Outrepo::getApprover, "");

        boolean update = update(updateWrapper);

        if (!update) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }

        return true;
    }

    @Override
    public boolean approve(Outrepo outrepo, String userName) {

        UpdateWrapper<Outrepo> updateWrapper = new UpdateWrapper<>();
        LambdaUpdateWrapper<Outrepo> lambda = updateWrapper.lambda();

        lambda.eq(BaseEntity::getId, outrepo.getId())
                .set(Outrepo::getApproveStatus, outrepo.getApproveStatus())
                .set(Outrepo::getApproveComments, outrepo.getApproveComments())
                .set(Outrepo::getApprover, userName)
                .set(Outrepo::getApproveTime, LocalDateTime.now());


        if (outrepo.getApproveStatus() == 0) {
            lambda.set(Outrepo::getStatus, 0);
        }

        boolean update = update(updateWrapper);

        return true;
    }

    @Override
    public boolean repoOut(Integer id) {

        Outrepo outrepo = getById(id);

        Integer applyId = outrepo.getApplyId();//申请单id
        Integer outorderId = outrepo.getOutorderId();//订单id

        //查询出库商品imei，修改仓库中的状态
        QueryWrapper<RefacOutGoods> refacOutGoodsQueryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<RefacOutGoods> outGoodsLambdaQueryWrapper = refacOutGoodsQueryWrapper.lambda();

        outGoodsLambdaQueryWrapper.select(RefacOutGoods::getGoodImei)
                .eq(RefacOutGoods::getOdoId, applyId);

        List<Object> objects = outGoodsService.listObjs(outGoodsLambdaQueryWrapper);

        UpdateWrapper<Defective> defectiveUpdateWrapper = new UpdateWrapper<>();
        LambdaUpdateWrapper<Defective> defectiveLambdaUpdateWrapper = defectiveUpdateWrapper.lambda();

        defectiveLambdaUpdateWrapper.in(Defective::getGoodImei, objects)
                .set(Defective::getGoodStatus, 3);

        boolean update = defectiveService.update(defectiveUpdateWrapper);

        //修改出库单出库状态  status =3
        UpdateWrapper<Outrepo> outrepoUpdateWrapper = new UpdateWrapper<>();
        LambdaUpdateWrapper<Outrepo> outrepoLambdaUpdateWrapper = outrepoUpdateWrapper.lambda();

        outrepoLambdaUpdateWrapper.eq(BaseEntity::getId, id)
                .set(Outrepo::getStatus, 3);

        boolean update1 = update(outrepoUpdateWrapper);

        //修改出库订单出库状态 statuss
        UpdateWrapper<Outorder> outorderUpdateWrapper = new UpdateWrapper<>();
        LambdaUpdateWrapper<Outorder> outorderLambdaUpdateWrapper = outorderUpdateWrapper.lambda();

        outorderLambdaUpdateWrapper.eq(BaseEntity::getId, outorderId)
                .set(Outorder::getStatus, 1);

        boolean update2 = outorderService.update(outorderUpdateWrapper);

        //修改出库申请单出库状态
        UpdateWrapper<RefacOutApply> outApplyUpdateWrapper = new UpdateWrapper<>();
        LambdaUpdateWrapper<RefacOutApply> outApplyLambdaUpdateWrapper = outApplyUpdateWrapper.lambda();

        outApplyLambdaUpdateWrapper.eq(BaseEntity::getId, applyId)
                .set(RefacOutApply::getStatus, 1);

        boolean update3 = outApplyService.update(outApplyUpdateWrapper);

        if (!update || !update1 || !update2 || !update3) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }

        return true;
    }


}
